package com.party.core.service.member.impl;

import com.google.common.base.Function;
import com.google.common.base.Strings;
import com.party.common.constant.Constant;
import com.party.common.paging.Page;
import com.party.common.utils.BigDecimalUtils;
import com.party.common.utils.DateUtils;
import com.party.common.utils.LangUtils;
import com.party.core.dao.read.member.MemberCopartnerCountReadDao;
import com.party.core.dao.read.member.MemberCopartnerDetailReadDao;
import com.party.core.dao.write.member.MemberCopartnerDetailWriteDao;
import com.party.core.model.BaseModel;
import com.party.core.model.member.CopartnerAnalyzeQuery;
import com.party.core.model.member.MemberCopartnerCount;
import com.party.core.model.member.MemberCopartnerDetail;
import com.party.core.model.member.MemberCopartnerDetailWithMember;
import com.party.core.service.member.IMemberCopartnerDetailService;
import com.sun.istack.NotNull;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;
import java.util.Set;

/**
 * 合伙人数据统计详情接口实现
 * Created by wei.li.
 *
 * @date 2018/1/16 0016
 * @time 11:49
 */
@Service
public class MemberCopartnerDetailService implements IMemberCopartnerDetailService {

    @Autowired
    private MemberCopartnerDetailReadDao memberCopartnerDetailReadDao;

    @Autowired
    private MemberCopartnerDetailWriteDao memberCopartnerDetailWriteDao;

    @Autowired
    private MemberCopartnerCountReadDao memberCopartnerCountReadDao;

    /**
     * 新增
     *
     * @param memberCopartnerDetail 统计详情
     * @return 编号
     */
    @Override
    public String insert(MemberCopartnerDetail memberCopartnerDetail) {
        BaseModel.preInsert(memberCopartnerDetail);
        boolean result = memberCopartnerDetailWriteDao.insert(memberCopartnerDetail);
        if (result) {
            return memberCopartnerDetail.getId();
        }
        return null;
    }


    /**
     * 更新
     *
     * @param memberCopartnerDetail 统计详情
     * @return 更新结果(true / false)
     */
    @Override
    public boolean update(MemberCopartnerDetail memberCopartnerDetail) {
        return memberCopartnerDetailWriteDao.update(memberCopartnerDetail);
    }

    /**
     * 逻辑删除
     *
     * @param id 实体主键
     * @return 删除结果(true / false)
     */
    @Override
    public boolean deleteLogic(@NotNull String id) {
        if (Strings.isNullOrEmpty(id)) {
            return false;
        }
        return memberCopartnerDetailWriteDao.deleteLogic(id);
    }

    /**
     * 物理删除
     *
     * @param id 实体主键
     * @return 删除结果(true / false)
     */
    @Override
    public boolean delete(@NotNull String id) {
        if (Strings.isNullOrEmpty(id)) {
            return false;
        }
        return memberCopartnerDetailWriteDao.delete(id);
    }

    /**
     * 批量逻辑删除
     *
     * @param ids 主键集合
     * @return 删除结果（true/fasle）
     */
    @Override
    public boolean batchDeleteLogic(@NotNull Set<String> ids) {
        if (CollectionUtils.isEmpty(ids)) {
            return false;
        }
        return memberCopartnerDetailWriteDao.batchDeleteLogic(ids);
    }

    /**
     * 批量物理删除
     *
     * @param ids 主键集合
     * @return 删除结果(true / false)
     */
    @Override
    public boolean batchDelete(@NotNull Set<String> ids) {
        if (CollectionUtils.isEmpty(ids)) {
            return false;
        }
        return memberCopartnerDetailWriteDao.batchDelete(ids);
    }

    /**
     * 获取统计详情
     *
     * @param id 主键
     * @return 统计详情
     */
    @Override
    public MemberCopartnerDetail get(String id) {
        return memberCopartnerDetailReadDao.get(id);
    }

    /**
     * 获取或者设置
     *
     * @param memberId 会员编号
     * @param date     日期
     * @return 合伙人统计详情
     */
    @Override
    public MemberCopartnerDetail getSet(String memberId, Date date) {
        return getSet(memberId, date, Constant.OPTION_ADD);
    }

    /**
     * 获取或者设置
     *
     * @param memberId 会员编号
     * @param date     日期
     * @param option   操作 add/sub
     * @return 合伙人统计详情
     */
    @Override
    public MemberCopartnerDetail getSet(String memberId, Date date, String option) {
        MemberCopartnerDetail memberCopartnerDetail = this.get(memberId, date, option);
        if (null != memberCopartnerDetail) {
            return memberCopartnerDetail;
        } else {
            MemberCopartnerCount memberCopartnerCount = memberCopartnerCountReadDao.findByMemberId(memberId);
            memberCopartnerDetail = new MemberCopartnerDetail(0, 0, 0, 0d, 0d, 0d, 0d, 0d, option);
            memberCopartnerDetail.setMemberId(memberId);
            memberCopartnerDetail.setCreateDate(date);
            if (null != memberCopartnerCount) {
                memberCopartnerDetail.setCountId(memberCopartnerCount.getId());
            }
            this.insert(memberCopartnerDetail);
        }
        return memberCopartnerDetail;
    }

    /**
     * 根据会员编号和时间获取
     *
     * @param memberId 会员编号
     * @param date     日期
     * @return 统计详情
     */
    @Override
    public MemberCopartnerDetail get(String memberId, Date date, String option) {
        return memberCopartnerDetailReadDao.findByMemberIdAndDate(memberId, date, option);
    }

    /**
     * 分页查询
     *
     * @param memberCopartnerDetail 统计详情
     * @param page                  分页信息
     * @return 统计详情列表
     */
    @Override
    public List<MemberCopartnerDetail> listPage(MemberCopartnerDetail memberCopartnerDetail, Page page) {
        return memberCopartnerDetailReadDao.listPage(memberCopartnerDetail, page);
    }

    /**
     * 查询所有
     *
     * @param memberCopartnerDetail 统计详情
     * @return 详情列表
     */
    @Override
    public List<MemberCopartnerDetail> list(MemberCopartnerDetail memberCopartnerDetail) {
        return memberCopartnerDetailReadDao.listPage(memberCopartnerDetail, null);
    }

    @Override
    public List<MemberCopartnerDetail> batchList(@NotNull Set<String> ids, MemberCopartnerDetail memberCopartnerDetail, Page page) {
        return null;
    }

    /**
     * 统计列表
     *
     * @param copartnerAnalyzeQuery 查询参数
     * @param page                  分页参数
     * @return 列表数据
     */
    @Override
    public List<MemberCopartnerDetailWithMember> sumList(CopartnerAnalyzeQuery copartnerAnalyzeQuery, Page page) {
        copartnerAnalyzeQuery.setOption(Constant.OPTION_ADD);
        List<MemberCopartnerDetailWithMember> list = memberCopartnerDetailReadDao.sumList(copartnerAnalyzeQuery, page);
        return LangUtils.transform(list, new Function<MemberCopartnerDetailWithMember, MemberCopartnerDetailWithMember>() {
            @Override
            public MemberCopartnerDetailWithMember apply(MemberCopartnerDetailWithMember memberCopartnerDetailWithMember) {
                memberCopartnerDetailWithMember
                        .setTotalBrokerage(BigDecimalUtils.round(memberCopartnerDetailWithMember.getTotalBrokerage(), 2));
                memberCopartnerDetailWithMember
                        .setTotalMoney(BigDecimalUtils.round(memberCopartnerDetailWithMember.getTotalMoney(), 2));
                return memberCopartnerDetailWithMember;
            }
        });
    }

    /**
     * 统计
     *
     * @param copartnerAnalyzeQuery 查询参数
     * @return 统计数据
     */
    @Override
    public MemberCopartnerDetailWithMember sum(CopartnerAnalyzeQuery copartnerAnalyzeQuery) {
        List<MemberCopartnerDetailWithMember> list = this.sumList(copartnerAnalyzeQuery, null);
        if (!CollectionUtils.isEmpty(list)) {
            return list.get(0);
        }
        return new MemberCopartnerDetailWithMember(0, 0, 0, 0d, 0d, 0d, 0d, 0d);
    }

    /**
     * 条件查询
     *
     * @param copartnerAnalyzeQuery 查询参数
     * @return 查询结果
     */
    @Override
    public List<MemberCopartnerDetail> queryList(CopartnerAnalyzeQuery copartnerAnalyzeQuery) {
        return memberCopartnerDetailReadDao.queryList(copartnerAnalyzeQuery);
    }

    @Override
    public void updateBrokerage(String memberId, Double brokerage, Boolean isContain, boolean isBegin, double withdrawalTotal) {
        MemberCopartnerDetail memberCopartnerDetail = this.getSet(memberId, DateUtils.today());
        if (null != memberCopartnerDetail.getTotalBrokerage()) {
            double add = BigDecimalUtils.add(memberCopartnerDetail.getTotalBrokerage(), brokerage);
            double round = BigDecimalUtils.round(add, 2);
            memberCopartnerDetail.setTotalBrokerage(round);
        } else {
            memberCopartnerDetail.setTotalBrokerage(0d);
        }

        if (!isContain) {
            if (null != memberCopartnerDetail.getMyBrokerage()) {
                double add = BigDecimalUtils.add(memberCopartnerDetail.getMyBrokerage(), brokerage);
                double round = BigDecimalUtils.round(add, 2);
                memberCopartnerDetail.setMyBrokerage(round);
            } else {
                memberCopartnerDetail.setMyBrokerage(0d);
            }
        }

//        if (isBegin) {
//            // 可提现
//            if (null != memberCopartnerDetail.getCanWithdrawal()) {
//                // 可结算
//                double balance = BigDecimalUtils.sub(memberCopartnerDetail.getTotalBrokerage(), memberCopartnerDetail.getNotBalance());
//                double canWithdrawal = BigDecimalUtils.sub(balance, withdrawalTotal);
//                memberCopartnerDetail.setCanWithdrawal(BigDecimalUtils.round(canWithdrawal, 2));
//            }
//        } else {
//            // 未结算
//            if (null != memberCopartnerDetail.getNotBalance()) {
//                double add = BigDecimalUtils.add(memberCopartnerDetail.getNotBalance(), brokerage);
//                memberCopartnerDetail.setNotBalance(BigDecimalUtils.round(add, 2));
//            } else {
//                memberCopartnerDetail.setNotBalance(0d);
//            }
//        }
        this.update(memberCopartnerDetail);
    }

    @Override
    public void updateSuccess(String projectId, String memberId) {
        MemberCopartnerDetail memberCopartnerDetail = this.getSet(memberId, DateUtils.today());
        if (null != memberCopartnerDetail.getSuccessNum()) {
            memberCopartnerDetail.setSuccessNum(memberCopartnerDetail.getSuccessNum() + 1);
        } else {
            memberCopartnerDetail.setSuccessNum(1);
        }
        this.update(memberCopartnerDetail);
    }

    @Override
    public void updateApplyNum(String projectId, String memberId) {
        MemberCopartnerDetail memberCopartnerDetail = this.getSet(memberId, DateUtils.today());
        if (null != memberCopartnerDetail.getApplyNum()) {
            memberCopartnerDetail.setApplyNum(memberCopartnerDetail.getApplyNum() + 1);
        } else {
            memberCopartnerDetail.setApplyNum(1);
        }
        this.update(memberCopartnerDetail);
    }

    @Override
    public void updateApplyRefund(String memberId, Double payment, String option) {
        MemberCopartnerDetail memberCopartnerDetail = this.getSet(memberId, DateUtils.today(), option);
        if (Constant.OPTION_ADD.equals(option)) {
            // 报名数
            memberCopartnerDetail.setApplyNum(memberCopartnerDetail.getApplyNum() - 1);
            if (payment > 0) {
                // 订单数
                memberCopartnerDetail.setOrderNum(memberCopartnerDetail.getOrderNum() - 1);
                // 累计资金
                double subTotalMoney = BigDecimalUtils.sub(memberCopartnerDetail.getTotalMoney(), payment);
                memberCopartnerDetail.setTotalMoney(BigDecimalUtils.round(subTotalMoney, 2));
            }
        } else if (Constant.OPTION_SUB.equals(option)) {
            // 报名数
            memberCopartnerDetail.setApplyNum(memberCopartnerDetail.getApplyNum() + 1);
            if (payment > 0) {
                // 订单数
                memberCopartnerDetail.setOrderNum(memberCopartnerDetail.getOrderNum() + 1);
                // 累计资金
                double subTotalMoney = BigDecimalUtils.add(memberCopartnerDetail.getTotalMoney(), payment);
                memberCopartnerDetail.setTotalMoney(BigDecimalUtils.round(subTotalMoney, 2));
            }
        }
        if (memberCopartnerDetail.getApplyNum() < 0) {
            memberCopartnerDetail.setApplyNum(0);
        }
        if (memberCopartnerDetail.getOrderNum() < 0) {
            memberCopartnerDetail.setOrderNum(0);
        }
        if (memberCopartnerDetail.getTotalMoney() < 0) {
            memberCopartnerDetail.setTotalMoney(0d);
        }
        this.update(memberCopartnerDetail);
    }

    @Override
    public void updateApplyRefundBrokerage(String memberId, float brokerage,
                                           boolean isMyBrokerage, String option,
                                           boolean isBegin, double withdrawalTotal) {
        MemberCopartnerDetail memberCopartnerDetail = this.getSet(memberId, DateUtils.today(), option);
        if (Constant.OPTION_ADD.equals(option)) {
            // 累计佣金
            double subTotalBrokerage = BigDecimalUtils.sub(memberCopartnerDetail.getTotalBrokerage(), brokerage);
            memberCopartnerDetail.setTotalBrokerage(BigDecimalUtils.round(subTotalBrokerage, 2));
            // 我的佣金
            if (isMyBrokerage) {
                double subMyBrokerage = BigDecimalUtils.sub(memberCopartnerDetail.getMyBrokerage(), brokerage);
                memberCopartnerDetail.setMyBrokerage(BigDecimalUtils.round(subMyBrokerage, 2));
            }

//            if (isBegin) {
//                    // 可结算
//                    double balance = BigDecimalUtils.sub(memberCopartnerDetail.getTotalBrokerage(), memberCopartnerDetail.getNotBalance());
//                    double canWithdrawal = BigDecimalUtils.sub(balance, withdrawalTotal);
//                    memberCopartnerDetail.setCanWithdrawal(BigDecimalUtils.round(canWithdrawal, 2));
//            } else {
//                // 不可提现
//                double subNotBalance = BigDecimalUtils.sub(memberCopartnerDetail.getNotBalance(), brokerage);
//                memberCopartnerDetail.setNotBalance(BigDecimalUtils.round(subNotBalance, 2));
//            }
        } else if (Constant.OPTION_SUB.equals(option)) {
            // 累计佣金
            double subTotalBrokerage = BigDecimalUtils.add(memberCopartnerDetail.getTotalBrokerage(), brokerage);
            memberCopartnerDetail.setTotalBrokerage(BigDecimalUtils.round(subTotalBrokerage, 2));
            // 我的佣金
            if (isMyBrokerage) {
                double subMyBrokerage = BigDecimalUtils.add(memberCopartnerDetail.getMyBrokerage(), brokerage);
                memberCopartnerDetail.setMyBrokerage(BigDecimalUtils.round(subMyBrokerage, 2));
            }

//            if (isBegin) {
//                double subCanWithdrawal = BigDecimalUtils.add(memberCopartnerDetail.getCanWithdrawal(), brokerage);
//                memberCopartnerDetail.setCanWithdrawal(BigDecimalUtils.round(subCanWithdrawal, 2));
//            } else {
//                // 不可提现
//                double subNotBalance = BigDecimalUtils.add(memberCopartnerDetail.getNotBalance(), brokerage);
//                memberCopartnerDetail.setNotBalance(BigDecimalUtils.round(subNotBalance, 2));
//            }
        }
        if (memberCopartnerDetail.getTotalBrokerage() < 0) {
            memberCopartnerDetail.setTotalBrokerage(0d);
        }
        if (memberCopartnerDetail.getMyBrokerage() < 0) {
            memberCopartnerDetail.setMyBrokerage(0d);
        }
        if (memberCopartnerDetail.getNotBalance() < 0) {
            memberCopartnerDetail.setNotBalance(0d);
        }
        if (memberCopartnerDetail.getCanWithdrawal() < 0) {
            memberCopartnerDetail.setCanWithdrawal(0d);
        }
        this.update(memberCopartnerDetail);
    }

    @Override
    public void updateOrderAnalyze(Float payment, String memberId) {
        MemberCopartnerDetail memberCopartnerDetail = this.getSet(memberId, DateUtils.today());
        if (null != memberCopartnerDetail.getOrderNum()) {
            memberCopartnerDetail.setOrderNum(memberCopartnerDetail.getOrderNum() + 1);
        } else {
            memberCopartnerDetail.setOrderNum(1);
        }
        if (null != memberCopartnerDetail.getTotalMoney()) {
            double add = BigDecimalUtils.add(memberCopartnerDetail.getTotalMoney(), payment);
            double round = BigDecimalUtils.round(add, 2);
            memberCopartnerDetail.setTotalMoney(round);
        } else {
            memberCopartnerDetail.setTotalMoney(Double.valueOf(payment));
        }
        this.update(memberCopartnerDetail);
    }

    @Override
    public void updateOrderAnalyzeSub(Float payment, String memberId, String option) {
        MemberCopartnerDetail memberCopartnerDetail = this.getSet(memberId, DateUtils.today(), option);
        if (Constant.OPTION_ADD.equals(option)) {
            double sub = BigDecimalUtils.sub(memberCopartnerDetail.getTotalMoney(), payment);
            sub = BigDecimalUtils.round(sub, 2);
            memberCopartnerDetail.setTotalMoney(sub);
            memberCopartnerDetail.setOrderNum(memberCopartnerDetail.getOrderNum() - 1);
        } else if (Constant.OPTION_SUB.equals(option)) {
            double add = BigDecimalUtils.add(memberCopartnerDetail.getTotalBrokerage(), payment);
            add = BigDecimalUtils.round(add, 2);
            memberCopartnerDetail.setTotalMoney(add);
            memberCopartnerDetail.setOrderNum(memberCopartnerDetail.getOrderNum() + 1);
        }
        this.update(memberCopartnerDetail);
    }

    @Override
    public void updateSuccessSub(String projectId, String memberId, String option) {
        MemberCopartnerDetail memberCopartnerDetail = this.getSet(memberId, DateUtils.today(), option);
        if (Constant.OPTION_ADD.equals(option)) {
            memberCopartnerDetail.setSuccessNum(memberCopartnerDetail.getSuccessNum() - 1);
        } else {
            memberCopartnerDetail.setSuccessNum(memberCopartnerDetail.getSuccessNum() + 1);
        }
        this.update(memberCopartnerDetail);
    }

    @Override
    public void updateCrowdfundSuccess(Float payment, String memberId) {
        MemberCopartnerDetail memberCopartnerDetail = this.getSet(memberId, DateUtils.today());
        memberCopartnerDetail.setOrderNum(memberCopartnerDetail.getOrderNum() + 1);

        double add = BigDecimalUtils.add(memberCopartnerDetail.getTotalMoney(), payment);
        double round = BigDecimalUtils.round(add, 2);
        memberCopartnerDetail.setTotalMoney(round);

        memberCopartnerDetail.setSuccessNum(memberCopartnerDetail.getSuccessNum() + 1);

        this.update(memberCopartnerDetail);
    }
}
